package com.sl.core.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.fhs.trans.advice.EasyTransResponseBodyAdvice;
import com.sl.common.page.PageList;
import com.sl.common.pojo.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.beans.PropertyDescriptor;
import java.net.URI;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Slf4j
@RestControllerAdvice
@Order
public class GlobalResponseSuccessHandler implements ResponseBodyAdvice {

    @Autowired(required = false)
    private EasyTransResponseBodyAdvice easyTransResponseBodyAdvice;


    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        return methodParameter.getDeclaringClass().isAnnotationPresent(RestController.class);
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        URI uri = serverHttpRequest.getURI();
        String query = uri.getQuery();
        if(StrUtil.contains(query,"export")){
            return o;
        }
        if (o instanceof CommonResult) {
            return pageToMap((CommonResult) o, methodParameter, mediaType, aClass, serverHttpRequest, serverHttpResponse);
        }

//        String packageName = "org.springdoc.webmvc.ui.SwaggerConfigResource";
        if (StrUtil.contains(methodParameter.getDeclaringClass().getName(),"org.springdoc")) {
            return o;
        }
        return pageToMap(CommonResult.data(o), methodParameter, mediaType, aClass, serverHttpRequest, serverHttpResponse);
    }

    private Object pageToMap(CommonResult commonResult, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        Object data = commonResult.getData();

        if (ObjectUtil.isNull(data)) {
            return commonResult;
        }
        if (!(data instanceof PageList)) {
            return commonResult;
        }
        PageList pageList = (PageList) data;

        Boolean pageIs = pageList.getPageIs();
        if (BooleanUtil.isFalse(pageIs)) {
            return commonResult;
        }
        //分页的话需要兼容一下
        if (ObjectUtil.isNotNull(easyTransResponseBodyAdvice)) {
            data = easyTransResponseBodyAdvice.beforeBodyWrite(pageList, methodParameter, mediaType, aClass, serverHttpRequest, serverHttpResponse);
//            pageList = (PageList) data;
            if (ObjectUtil.isNotNull(data)) {
                List list = ((Collection) data).stream().toList();
                pageList.clear();
                pageList.addAll(list);
            }
        }


        Map pageMap = new LinkedHashMap();
        PropertyDescriptor[] propertyDescriptors = BeanUtil.getPropertyDescriptors(pageList.getClass());
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            pageMap.put(propertyDescriptor.getName(), ReflectUtil.getFieldValue(pageList, propertyDescriptor.getName()));
        }


//        List records = pageList.getRecords();
//        List<Object> maps = new ArrayList<>();
//        for (Object record : pageList) {
////            propertyDescriptors = BeanUtil.getPropertyDescriptors(record.getClass());
////            Map map = new LinkedHashMap();
////            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
////                map.put(propertyDescriptor.getName(), ReflectUtil.getFieldValue(record, propertyDescriptor.getName()));
////            }
//            maps.add(record);
//        }
        pageMap.put("records", pageList.stream().collect(Collectors.toList()));
        commonResult.setData(pageMap);
        return commonResult;
    }

}
